home *** CD-ROM | disk | FTP | other *** search
/ CD Ware Multimedia 1995 May / cd Ware (Juegos) Epimundo.iso / DOS / C / STRFTIM.ZIP / STRFTIME.C < prev    next >
Encoding:
C/C++ Source or Header  |  1988-12-31  |  8.0 KB  |  275 lines

  1. /* file strftime.c */
  2.  
  3. /*
  4.    routine to convert a time structure into a formatted string
  5.    based on the standard ANSI C function as described in K & R 2nd ed.
  6. */
  7.  
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10. #include <string.h>
  11. #include <time.h>
  12. #include <dos.h>
  13. #include <assert.h>
  14.  
  15. #include "strftime.h"
  16.  
  17. static void putcode(char *str, int i1, int i2, int i3, char sep);
  18. static void showtim(char *str, const struct tm *nows);
  19. static void strdd(char *str, int num);
  20. static void showdate(char *str, const struct tm *tp);
  21.  
  22. static int country_flag = 0;
  23. static struct country rec;
  24.  
  25. static char *weekdays[] =
  26. {
  27.     "Sunday",
  28.     "Monday",
  29.     "Tuesday",
  30.     "Wednesday",
  31.     "Thursday",
  32.     "Friday",
  33.     "Saturday"
  34. };
  35.  
  36. static char *months[] =
  37. {
  38.     "January",
  39.     "February",
  40.     "March",
  41.     "April",
  42.     "May",
  43.     "June",
  44.     "July",
  45.     "August",
  46.     "September",
  47.     "October",
  48.     "November",
  49.     "December"
  50. };
  51.  
  52. size_t strftime(char *s, size_t smax, const char *fmt, const struct tm *tp)
  53. {
  54.     size_t retlen = 0;
  55.     char str[80];
  56.     int l;
  57.  
  58.     if (country_flag == 0)
  59.     {
  60.         country_flag = 1;
  61.         assert(country(0, &rec) != NULL);
  62.     }
  63.  
  64.     while (*fmt)
  65.     {
  66.         if (*fmt != '%')
  67.         {
  68.             str[0] = *fmt++;
  69.             str[1] = '\0';
  70.         }
  71.         else
  72.         {
  73.             fmt++;
  74.             switch (*fmt++)
  75.             {
  76.                 case 'c': /* local time and date representation */
  77.                     assert(rec.co_date >= 0 && rec.co_date < 3);
  78.                     switch(rec.co_date)
  79.                     {
  80.                         case 0: /* h m s  m d y */
  81.                             showtim(str, tp);
  82.                             strcat(str, "  ");
  83.                             showdate(&str[strlen(str)], tp);
  84.                             break;
  85.                         case 1: /* h m s  d m y */
  86.                             showtim(str, tp);
  87.                             strcat(str, "  ");
  88.                             showdate(&str[strlen(str)], tp);
  89.                             break;
  90.                         case 2: /* y m d  h m s */
  91.                             showdate(str, tp);
  92.                             strcat(str, "  ");
  93.                             showtim(&str[strlen(str)], tp);
  94.                             break;
  95.                     }
  96.                     break;
  97.                 case 'x': /* local date representation */
  98.                     showdate(str, tp);
  99.                     break;
  100.                 case 'X': /* local time representation */
  101.                     showtim(str, tp);
  102.                     break;
  103.  
  104.                 case 'y': /* year without century (00-99) */
  105.                     strdd(str, tp->tm_year);
  106.                     break;
  107.                 case 'Y': /* year with century */
  108.                     sprintf(str, "%04d", tp->tm_year + 1900);
  109.                     break;
  110.                 case 'b': /* abbreviated month name */
  111.                     strncpy(str, months[tp->tm_mon], 3);
  112.                     str[3] = '\0';
  113.                     break;
  114.                 case 'B': /* full month name */
  115.                     strcpy(str, months[tp->tm_mon]);
  116.                     break;
  117.                 case 'm': /* month (01-12) */
  118.                     strdd(str, tp->tm_mon + 1);
  119.                     break;
  120.                 case 'd': /* day of the month (01-31) */
  121.                     strdd(str, tp->tm_mday);
  122.                     break;
  123.                 case 'H': /* hour (24-hour clock) (00-23) */
  124.                     strdd(str, tp->tm_hour);
  125.                     break;
  126.                 case 'I': /* hour (12-hour clock) (01-12) */
  127.                     strdd(str, (tp->tm_hour + 11) % 12 + 1);
  128.                     break;
  129.                 case 'p': /* local equivalent of AM or PM */
  130.                     strcpy(str, tp->tm_hour < 12 ? "AM" : "PM");
  131.                     break;
  132.                 case 'M': /* minute (00-59) */
  133.                     strdd(str, tp->tm_min);
  134.                     break;
  135.                 case 'S': /* second (00-59) */
  136.                     strdd(str, tp->tm_sec);
  137.                     break;
  138.                 case 'a': /* abbreviated weekday name. */
  139.                     strncpy(str, weekdays[tp->tm_wday], 3);
  140.                     str[3] = '\0';
  141.                     break;
  142.                 case 'A': /* full weekday name */
  143.                     strcpy(str, weekdays[tp->tm_wday]);
  144.                     break;
  145.                 case 'w': /* weekday (0 - 6, Sunday is 0) */
  146.                     sprintf(str, "%d", tp->tm_wday);
  147.                     break;
  148.                 case 'j': /* day of the year (001-366) */
  149.                     sprintf(str, "%03d", tp->tm_yday + 1);
  150.                     break;
  151.                 case 'U':
  152.                     /*
  153.                         week number of the year (Sunday as 1st day of week)
  154.                         (01-53)
  155.                     */
  156.                     strdd(str, (tp->tm_yday + 13 - tp->tm_wday) / 7);
  157.                     break;
  158.                 case 'W':
  159.                     /*
  160.                         week number of the year (Monday as 1st day of week)
  161.                         (01-53)
  162.                     */
  163.                     strdd(str, (tp->tm_yday + (7 - tp->tm_wday) % 7) / 7 + 1);
  164.                     break;
  165.                 case 'Z': /* time zone, if any */
  166.                     strncpy(str, tzname[daylight], 3);
  167.                     str[3] = '\0';
  168.                     break;
  169.                 case '%':
  170.                     str[0] = '%';
  171.                     str[1] = '\0';
  172.                     break;
  173.                 default: /* ignore it */
  174.                     str[0] = '\0';
  175.             }
  176.         }
  177.         l = strlen(str);
  178.         retlen += l;
  179.         if (retlen > smax) return 0;
  180.         strncpy(s, str, l);
  181.         s += l;
  182.     }
  183.     retlen++;
  184.     if (retlen > smax) return 0;
  185.     *s = '\0';
  186.     return retlen;
  187. }
  188.  
  189. static void showtim(char *str, const struct tm *nows)
  190. {
  191.     int hrs, min, sec, hour12;
  192.  
  193.     hrs = nows->tm_hour;
  194.     assert(hrs >= 0 && hrs < 24);
  195.     min = nows->tm_min;
  196.     assert(min >= 0 && min < 60);
  197.     sec = nows->tm_sec;
  198.     assert(sec >= 0 && sec < 60);
  199.     assert(rec.co_time == 0 || rec.co_time == 1);
  200.     switch(rec.co_time)
  201.     {
  202.         case 0: /* 12 hour clock */
  203.             hour12 = hrs % 12;
  204.             putcode(str,
  205.                 (hour12 == 0) ? 12 : hour12, min, sec, rec.co_tmsep[0]);
  206.             strcat(str, hrs < 12 ? "AM" : "PM");
  207.             break;
  208.         case 1: /* 24 hour clock */
  209.             putcode(str, hrs, min, sec, rec.co_tmsep[0]);
  210.             break;
  211.     }
  212. }
  213.  
  214. static void showdate(char *str, const struct tm *tp)
  215. {
  216.     assert(rec.co_date >= 0 && rec.co_date < 3);
  217.     switch(rec.co_date)
  218.     {
  219.         case 0: /* m d y */
  220.             putcode
  221.                 (
  222.                     str,
  223.                     tp->tm_mon + 1,
  224.                     tp->tm_mday,
  225.                     tp->tm_year,
  226.                     rec.co_dtsep[0]
  227.                 );
  228.             break;
  229.         case 1: /* d m y */
  230.             putcode
  231.                 (
  232.                     str,
  233.                     tp->tm_mday,
  234.                     tp->tm_mon + 1,
  235.                     tp->tm_year,
  236.                     rec.co_dtsep[0]
  237.                 );
  238.             break;
  239.         case 2: /* y m d */
  240.             putcode
  241.                 (
  242.                     str,
  243.                     tp->tm_year,
  244.                     tp->tm_mon + 1,
  245.                     tp->tm_mday,
  246.                     rec.co_dtsep[0]
  247.                 );
  248.             break;
  249.     }
  250. }
  251.  
  252. static void putcode(char *str, int i1, int i2, int i3, char sep)
  253. {
  254.     assert(i1 >= 0);
  255.     assert(i1 <= 99);
  256.     assert(i2 >= 0);
  257.     assert(i2 <= 99);
  258.     assert(i3 >= 0);
  259.     assert(i3 <= 99);
  260.     strdd(str, i1);
  261.     str[2] = sep;
  262.     strdd(&str[3], i2);
  263.     str[5] = sep;
  264.     strdd(&str[6], i3);
  265. }
  266.  
  267. static void strdd(char *str, int num)
  268. {
  269.     str[0] = num / 10 + '0';
  270.     str[1] = num % 10 + '0';
  271.     str[2] = '\0';
  272. }
  273.  
  274. /* end of file strftime.c */
  275.